package com.duojuhe.websocket.subscriber.listener;


import com.alibaba.fastjson.JSONObject;
import com.duojuhe.common.utils.thread.ThreadUtils;
import com.duojuhe.coremodule.chat.im.entity.ChatGroupUser;
import com.duojuhe.coremodule.chat.im.mapper.ChatGroupUserMapper;
import com.duojuhe.coremodule.chat.im.mapper.ChatUsersFriendsMapper;
import com.duojuhe.websocket.EventCodes;
import com.duojuhe.websocket.SocketMessage;
import com.duojuhe.websocket.SocketUtil;
import com.duojuhe.common.enums.chat.ImChatEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Description 集群聊天消息监听器
 * @Date 2020/3/29 15:07
 */
@Slf4j
@Component
public class ImMessageListener implements MessageListener {
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private ChatGroupUserMapper chatGroupUserMapper;
    @Resource
    private ChatUsersFriendsMapper chatUsersFriendsMapper;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        RedisSerializer<JSONObject> valueSerializer = redisTemplate.getValueSerializer();
        JSONObject jsonObject = valueSerializer.deserialize(message.getBody());
        log.info("监听集群IM Websocket消息--- {}", jsonObject);
        //将字符串转成对象
        if (jsonObject==null){
            log.info("监听集群IM Websocket消息为空");
            return;
        }
        log.info("监听集群IM Websocket消息--- {}", jsonObject);
        //消息事件类型
        String eventType = jsonObject.getString("eventType");
        //消息事件内容
        JSONObject jsonMessageData = jsonObject.getJSONObject("messageData");
        if (jsonMessageData==null){
            log.info("监听集群IM Websocket消息jsonMessageData不可为空");
            return;
        }
        if (EventCodes.EVENT_TALK.getEvent().equals(eventType)){
            //聊天事件
            eventTalkHandle(jsonMessageData);
        }else if (EventCodes.EVENT_ONLINE_STATUS.getEvent().equals(eventType)){
            //在线状态事件
            eventOnlineStatusHandle(jsonMessageData);
        }else if (EventCodes.EVENT_KEYBOARD.getEvent().equals(eventType)){
            //键盘事件
            eventKeyboardHandle(jsonMessageData);
        }else if (EventCodes.EVENT_REVOKE_TALK.getEvent().equals(eventType)){
            //撤回事件
            eventRevokeHandle(jsonMessageData);
        }else if (EventCodes.EVENT_DELETE_TALK.getEvent().equals(eventType)){
            //删除事件
            eventDeleteHandle(jsonMessageData);
        }

    }



    /**
     * 聊天消息事件处理
     * @param jsonObject
     */
    private void eventTalkHandle(JSONObject jsonObject){
        //发送者id
        String senderId = jsonObject.getString("senderId");
        //接收对象id
        String receiverId = jsonObject.getString("receiverId");
        //聊天类型
        Integer talkType = jsonObject.getInteger("talkType");
        //是否给自己发送消息
        Boolean sendSenderSelfFlag = jsonObject.getBoolean("sendSenderSelfFlag");
        //聊天消息对象转换
        SocketMessage socketMessage = SocketMessage.eventSendData(jsonObject, EventCodes.EVENT_TALK);
        //给自己通知一份消息
        if (sendSenderSelfFlag){
            threadSendMessageMessageToUserId(senderId,socketMessage);
        }
        if (ImChatEnum.TalkType.PRIVATE_CHAT.getKey().equals(talkType)){
            //给接受者发送消息
            threadSendMessageMessageToUserId(receiverId,socketMessage);
        }else if (ImChatEnum.TalkType.GROUP_CHAT.getKey().equals(talkType)){
            //IM yes 标识
            Integer yes = ImChatEnum.IM_YES_NO.YES.getKey();
            //群聊
            List<ChatGroupUser> chatGroupUserList = chatGroupUserMapper.queryChatGroupUserListByGroupId(receiverId);
            for (ChatGroupUser groupUser:chatGroupUserList){
                //用户id
                String userId = groupUser.getUserId();
                if (yes.equals(groupUser.getIsQuit()) || senderId.equals(userId)){
                    //已经退群了 或者接受者是当前发送者 则不发送
                    continue;
                }
                threadSendMessageMessageToUserId(userId,socketMessage);
            }
        }
    }


    /**
     * 键盘事件
     * @param jsonObject
     */
    private void eventKeyboardHandle(JSONObject jsonObject){
        //接收对象id
        String receiverId = jsonObject.getString("receiverId");
        if (StringUtils.isBlank(receiverId)){
            return;
        }
        //聊天消息对象转换
        SocketMessage socketMessage = SocketMessage.eventSendData(jsonObject, EventCodes.EVENT_KEYBOARD);
        //给指定用户id通知一份消息
        threadSendMessageMessageToUserId(receiverId,socketMessage);
    }

    /**
     * 撤回事件
     * @param jsonObject
     */
    private void eventRevokeHandle(JSONObject jsonObject){
        //发送者id
        String senderId = jsonObject.getString("senderId");
        //接收对象id
        String receiverId = jsonObject.getString("receiverId");
        //聊天类型
        Integer talkType = jsonObject.getInteger("talkType");
        //聊天消息对象转换
        SocketMessage socketMessage = SocketMessage.eventSendData(jsonObject, EventCodes.EVENT_REVOKE_TALK);
        if (ImChatEnum.TalkType.PRIVATE_CHAT.getKey().equals(talkType)){
            //给接受者发送消息
            threadSendMessageMessageToUserId(receiverId,socketMessage);
        }else if (ImChatEnum.TalkType.GROUP_CHAT.getKey().equals(talkType)){
            //IM yes 标识
            Integer yes = ImChatEnum.IM_YES_NO.YES.getKey();
            //群聊
            List<ChatGroupUser> chatGroupUserList = chatGroupUserMapper.queryChatGroupUserListByGroupId(receiverId);
            for (ChatGroupUser groupUser:chatGroupUserList){
                //用户id
                String userId = groupUser.getUserId();
                if (yes.equals(groupUser.getIsQuit()) || senderId.equals(userId)){
                    //已经退群了 或者接受者是当前发送者 则不发送
                    continue;
                }
                threadSendMessageMessageToUserId(userId,socketMessage);
            }
        }
    }

    /**
     * 删除事件
     * @param jsonObject
     */
    private void eventDeleteHandle(JSONObject jsonObject){
        //接收对象id
        String senderId = jsonObject.getString("senderId");
        if (StringUtils.isBlank(senderId)){
            return;
        }
        //聊天消息对象转换
        SocketMessage socketMessage = SocketMessage.eventSendData(jsonObject, EventCodes.EVENT_DELETE_TALK);
        //给指定用户id通知一份消息
        threadSendMessageMessageToUserId(senderId,socketMessage);
    }


    /**
     * 在线状态事件
     * @param jsonObject
     */
    private void eventOnlineStatusHandle(JSONObject jsonObject){
        //用户id
        String userId = jsonObject.getString("userId");
        if (StringUtils.isBlank(userId)){
            return;
        }
        List<String> userIdList = chatUsersFriendsMapper.queryChatUsersFriendsListByUserId(userId);
        for (String uId:userIdList){
            //聊天消息对象转换
            SocketMessage socketMessage = SocketMessage.eventSendData(jsonObject, EventCodes.EVENT_ONLINE_STATUS);
            //给指定用户id通知一份消息
            threadSendMessageMessageToUserId(uId,socketMessage);
        }
    }


    /**
     * 发送消息
     * @param receiverId
     * @param socketMessage
     */
    private void threadSendMessageMessageToUserId(String receiverId,SocketMessage socketMessage){
        //给指定用户id通知一份消息
        ThreadUtils.execute(() -> SocketUtil.sendMessageToUserId(receiverId, socketMessage));
    }
}